package com.mumulx.check.redis.util;

import lombok.extern.slf4j.Slf4j;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 *  Created by IntelliJ IDEA.
 *  User: 木木
 *  Date: 2020/11/3
 *  Time: 13:51
 * astDFS工具类【实现文件上传、下载、删除、查询】
 */
@Component
@Slf4j
public class FastDfsClientUtil {


    private TrackerClient trackerClient = null;
    private TrackerServer trackerServer = null;
    private StorageServer storageServer = null;
    private StorageClient1 storageClient = null;

    public FastDfsClientUtil(){
        try {
            ClientGlobal.initByProperties("fastdfs-client.properties");
            trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
            storageServer = null;
            storageClient = new StorageClient1(trackerServer, storageServer);
            /**解决启动后第一次上传文件出错
             * 如果客户端服务启动，成功链接到dfs服务器，如果在network_timeout时间内，dfs服务没有接收到任何请求信息，会吧这个客户端踢掉！**/
            ProtoCommon.activeTest(trackerServer.getSocket());

        } catch (IOException e) {
            log.error("---获取fastdfs文件系统出错");
            e.printStackTrace();
        } catch (MyException e) {
            log.error("---获取fastdfs文件系统出错");
            e.printStackTrace();
        }

    }

  public Map<String,String> handlePrtUpload(List<MultipartFile> prts) throws IOException {
      Map<String, String> map = new HashMap<>();
      for (MultipartFile prt : prts) {
          //prt原本名称
          String prtName = prt.getOriginalFilename();
          //上传所携带的元数据信息
          NameValuePair[] metas = new NameValuePair[1];
          metas[0] = new NameValuePair("fileName", prtName);

          String prtUploadName = uploadFile(prt.getBytes(), "prt",metas);
          log.info("文件上传了---"+prtName+"："+prtUploadName);
          map.put(prtName, prtUploadName);
      }
      return map;
  }


  /**
   * 上传文件方法
   * <p>Title: uploadFile</p>
   * <p>Description: </p>
   * @param fileName 文件全路径
   * @param extName 文件扩展名，不包含（.）
   * @param metas 文件扩展信息
   * @return
   * @throws Exception
   */
    public String uploadFile(String fileName, String extName, NameValuePair[] metas) {
        log.info("-----开始上传文件");
        String result=null;
        try {
            log.info("要上传的文件为："+fileName);
            result = storageClient.upload_file1(fileName, extName, metas);
            log.info("文件上传成功存储路径为："+result);

        } catch (IOException e) {
            log.error("-----文件上传出错");
            e.printStackTrace();
        } catch (MyException e) {
            log.error("-----文件上传出错");
            e.printStackTrace();
        }
        return result;
    }


    /**
     *
     * @param fileName 文件的磁盘路径名称 如：D:/image/aaa.jpg
     * @param extName 文件的扩展名 如 txt jpg等
     * @return null为失败
     */
    public  String uploadFile(String fileName, String extName) {
        return uploadFile(fileName, extName, null);
    }

    /**
     * 上传文件方法
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileContent 文件的内容，字节数组
     * @param extName 文件扩展名
     * @param metas 文件扩展信息
     * @return
     * @throws Exception
     */
    public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) {
        String result=null;
        try {
            result = storageClient.upload_file1(fileContent, extName, metas);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 上传文件
     * @param fileContent  文件的字节数组
     * @param extName  文件的扩展名 如 txt  jpg png 等
     * @return null为失败
     */
    public String uploadFile(byte[] fileContent, String extName) {
        return uploadFile(fileContent, extName, null);
    }

    /**
     * 文件下载到磁盘
     * @param path 图片路径
     * @param output 输出流 中包含要输出到磁盘的路径
     * @return -1失败,0成功
     */
    public int download_file(String path, BufferedOutputStream output) {
        int result=-1;
        try {
            byte[] b = storageClient.download_file1(path);
            try{
                if(b != null){
                    output.write(b);
                    result=0;
                }
            }catch (Exception e){} //用户可能取消了下载
            finally {
                if (output != null){
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 获取文件数组
     * @param path 文件的路径 如group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
     * @return
     */
    public byte[] download_bytes(String path) {
        byte[] b=null;
        try {
            b = storageClient.download_file1(path);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return b;
    }

    /**
     * 删除文件
     * @param group 组名 如：group1
     * @param storagePath 不带组名的路径名称 如：M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
     * @return -1失败,0成功
     */
    public Integer delete_file(String group ,String storagePath){
        int result=-1;
        try {
            result = storageClient.delete_file(group, storagePath);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return  result;
    }
    /**
     *
     * @param storagePath  文件的全部路径 如：group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
     * @return -1失败,0成功
     * @throws IOException
     * @throws Exception
     */
    public Integer delete_file(String storagePath){
        int result=-1;
        try {
            result = storageClient.delete_file1(storagePath);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return  result;
    }

    /**
     * 获取远程服务器文件资源信息
     * @param groupName   文件组名 如：group1
     * @param remoteFileName M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
     * @return
     */
    public FileInfo getFile(String groupName, String remoteFileName){
        try {
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public NameValuePair[] getMetadata(String fileName){
        try {
            return storageClient.get_metadata1(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public void delete_file(List<String> files) {
        log.info("开始删除失效文件："+files);
        files.forEach(file->{
            log.info(file);
            delete_file(file);
        });
        log.info("文件删除成功");


    }
}